#include "stdafx.h"
#include "GSE_CNet.h"
#include "GSE_CConnector.h"
#include "GSE_CListener.h"
#include "GSE_Log.h"
namespace GSE
{
	CNet * CNet::m_pInstance = NULL;
	boost::mutex mNet;

	INet * INet::CreateModule(bool bMultiThread)
	{
		if ( NULL == CNet::m_pInstance )
		{
			boost::lock_guard<boost::mutex> guard(mNet);
			if ( NULL == CNet::m_pInstance )
			{
				CNet::m_pInstance = new CNet(bMultiThread);
			}
		}
		return CNet::m_pInstance;
	}

	void INet::DestroyModule()
	{
		boost::lock_guard<boost::mutex> guard(mNet);
		delete CNet::m_pInstance;
		CNet::m_pInstance = NULL;
	}


	INet * INet::InstancePtr()
	{
		if ( NULL == CNet::m_pInstance )
		{
			CreateModule(false);
		}
		return CNet::m_pInstance;
	}


	CNet::CNet(bool bUseMT):m_bMultiThreadModel(bUseMT)
	{
		m_uMaxMessageLength = 128 * 1024;
		m_lpThreadPool = new CThreadPool();
		m_lpThreadPool->Init(bUseMT);
	}

	CNet::~CNet()
	{
		m_Connectors.clear();
		m_Listeners.clear();
		delete m_lpThreadPool;
	}

	IListener * CNet::CreateListener()
	{
		shared_ptr<IListener> lpListener(new CListener(m_lpThreadPool));
		m_Listeners.insert(lpListener);
		return lpListener.get();
	}

	IConnector* CNet::CreateConnector()
	{
		shared_ptr<IConnector> lpConnector(new CConnector(m_lpThreadPool->GetIOService()));
		m_Connectors.insert(lpConnector);
		return lpConnector.get();
	}

	uint CNet::Run()
	{
		if ( m_bMultiThreadModel )
		{
			throw std::invalid_argument("Do Not Call this function, because use multithread model!");
		}
		uint uRet = 0;

		for( auto i = m_Connectors.begin();i != m_Connectors.end(); i++ )
		{
			uRet += (*i)->Run();
		}
		for( auto i = m_Listeners.begin();i != m_Listeners.end(); i++ )
		{
			uRet += (*i)->Run();
		}
		return uRet;
	}

	void CNet::DestroyListener( IListener * lpListener )
	{
		for ( auto i = m_Listeners.begin(); i != m_Listeners.end(); ++i )
		{
			if ( i->get() == lpListener )
			{
				(*i)->Cancel();
				m_Listeners.erase(i);
				break;
			}
		}
	}

	void CNet::DestroyConnector( IConnector * lpConnector )
	{
		for ( auto i = m_Connectors.begin(); i != m_Connectors.end(); ++i )
		{
			if ( i->get() == lpConnector )
			{
				m_Connectors.erase(i);
				break;
			}
		}
	}

	void CNet::SetMaxMessageLength(uint uMax)
	{
		m_uMaxMessageLength = uMax;
	}

	uint CNet::GetMaxMessageLength()
	{
		return m_uMaxMessageLength;
	}
}